<!--
 * @Author: weidewei
 * @Date: 2025-10-27 15:01:40
 * @LastEditors: weidewei
 * @LastEditTime: 2025-10-30 09:57:19
 * @Description: 
 * @FilePath: \2025-front-face\js\数据类型转换.html
-->
<script>
  /*
   * 1、大家应该听过javascript是一种动态（弱）类型的语言，那这动态（弱）类型从哪里体现呢
   * 		1、js取值非常的灵活
   * 			如果某个地方需要的数据类型是布尔值，这时候你并不需要给个布尔值，你可以给任意的数据类型，js会自动的帮你转成它想要的布尔值
   * 		2、当js在运算的时候，它期望你给的一个数据为数字类型的，但是你给了一个字符串类型的，这时候你不必担心程序会挂，js也会自动帮你把字符串转成数字类型
   * 		3、所以js还是很贴心的，想你所想，做你所做。让你感觉暧暧的。但是有利就有弊，有时候会出现一些你意想不到的结果。所以最好还是要明确数据类型
   *
   * 2、数据类型转换
   * 	1、虽然变量没有类型限制，可以随时赋予任意值（ES6里引入了常量这个概念，就不能随心所欲了），但是数据运算是有类型限制的。所以你有两种选择
   * 		1、要么安分守已，主动去转
   * 		2、要么放荡不羁，被动去转
   * 		3、这个就是我们要说的类型转换的两种方式
   */

  /*
   * 类型转换
   * 	把一种数据类型转换成另外一种数据类型
   * 	1、显式类型转换
   * 		调用内置方法，主动将数据转换
   * 	2、隐式类型转换
   * 		不同类型数据之间进行运算会引发隐式类型转换，这个过程是js自动完成的，用户看不到
   *
   * Number()
   * 	1、undefined		NaN
   * 	2、null			0
   * 	3、布尔值		true为1，false为0
   * 	4、字符串
   * 		1、空字符串，空格字符串转为0
   * 		2、非空字符串，并且内容为纯数字（包含进制与科学表示法）转成对应的数字
   * 		3、其余都是NaN
   * 	5、数字		原来的数字
   * 	6、对象
   * 		1、对象、函数转成NaN
   *		2、空数组转为0，数组里只有一个数据并且这个数据能转成数字，则转成对应的数字，其它都转成NaN
   *
   * 	parseInt()、parseFloat()、isNaN()在ES6里把这两个方法移植到了Number对象身上，用法与行为都没有变化
   * 	更直接，只有当参数为NaN才返回true，非NaN一律返回false
   * 	此方法不会把参数用Number()转换
   *
   * String()
   * 	基本数据类型、null、undefined的结果就是给数据加上引号变成字符串
   * 	对象
   * 		1、数组的结果为把所有中括号去掉，外面加个引号
   * 		2、对象的结果为'[object Object]'（除了日期对象）
   * 		3、函数的结果为在函数整体外面加个引号
   *
   * Boolean()
   * 	1、undefined		false
   * 	2、null			false
   * 	3、数字
   * 		+0、-0、NaN转布尔值的结果为false，其它的转布尔值的结果为true
   * 	4、布尔值	转为对应的值
   * 	5、字符串
   * 		空字符串转布尔值的结果为false，其它（包括空格字符串）的都转成true
   * 	6、对象转布尔值都是true
   */

  console.log(Number(null)); // 0
  console.log(Number(undefined)); // NaN
  console.log(Number("1")); // 1
  console.log(Number("1eee")); // NaN 不是纯数字全部转成NaN
  console.log(Number("")); // 0
  console.log(Number(" ")); // 0
  console.log(Number({})); // NaN
  console.log(Number(function fn() {})); // NaN
  console.log(Number([])); // 0 空数组
  console.log(Number([1, 2, 3])); // NaN
  console.log(Number([1])); // 1 数组仅有一项
  console.log(Number(NaN)); // NaN

  console.log(String(null)); // 'null'
  console.log(String(undefined)); // 'undefined'
  console.log(String(true)); // 'true'
  console.log(String(false)); // 'false'
  console.log(String(123)); // '123'
  console.log(String(NaN)); // 'NaN'
  console.log(String([])); // ''
  console.log(String(" ")); // ' '
  console.log(String([1, 2, 3])); // '1,2,3'
  console.log(String([1])); // '1'
  console.log(String({})); // '[object Object]' p.valueOf().toString()
  console.log(String(function () {})); // 'function (){}'

  console.log(Boolean(null)); // false
  console.log(Boolean(undefined)); // false
  console.log(Boolean(0)); // false
  console.log(Boolean(-0)); // false
  console.log(Boolean("")); // false
  console.log(Boolean(" ")); // true
  console.log(Boolean({})); // true
  console.log(Boolean([])); // true
  console.log(Boolean(function () {})); // true
  console.log(Boolean(NaN)); // false

  // 相等运算符比较
  /*
   * 比较运算符
   * 	==		相等（值相等就相等）
   *	===		严格相等（值与类型都相等才相等）
   *	!=		不相等（值不相等就不相等）
   *	!==		严格不相等（值与类型都不相等才不相等）
   *
   * 相等比较
   * 	1、不同类型的原始类型数据，把所有的数据转成数字后进行对比
   * 	2、null与undefined除了它们自己与自己、自己与对方相等，与其它的任何数据都不相等
   * 	3、对象与原始类型数据比较时，把对象转成原始值，再进行比较
   * 	4、对象与对象类型比较时，比较的是他们的引用地址，除非引用地址相同，否则都不相等
   *
   * 总结：
   * 	1、原始类型对比，转成数字对比
   * 	2、对象类型对比，把对象转成字符串，然后看对方的类型，如果不一样，都转成数字对比。对象与对象比较，比较引用地址
   * 	3、null与undefined，自己与自己、自己与对方相等。与其它任何数据都不相等
   *
   *
   * 严格相等
   * 	先比较类型是否一样，不一样直接返回false，一样的话再遵循相等比较的规则
   *
   * 不相等
   * 	与相等比较的规则一样，只是结果相反
   *
   * 严格不相等
   * 	与严格相等的规则一样，只是结果相反
   *
   */

   console.log(undefined == 0) // false
   console.log(null == 0) // false
   console.log(null == undefined) // true
   console.log(null == null) // true
   console.log(NaN == NaN) // false: 两端存在NaN： false  
   console.log([] == []) // false: 比较的是对象地址
   console.log([] == {}) // false: 比较的是对象地址
   console.log({} == 0) // false
   console.log([] == 0) //  true
   console.log({} == '') //  false
   console.log(undefined == {}) // false

   



</script>
